﻿using Microsoft.AspNetCore.StaticFiles;
using Zhp.Common.Helper;
using Zhp.Common.WebApp;
using Zhp.Entity.Common;
using Zhp.Entity.SysEnum;
using Zhp.IService.Common;
using Zhp.Model.Common;
using Zhp.Service.Base;
using Zhp.SqlSugar.Repository;

namespace Zhp.Service.Common
{
    public class FileService : BaseService<SysFile>, IFileService
    {

        public FileService(ICurrentUser currentUser, IBaseRepository<SysFile> rep)
        {
            _currentUser = currentUser;
            _rep = rep;
        }

        public async Task<ObjectRet<UploadFileRet>> UploadFile(UploadFileParam param)
        {
            var ret = new ObjectRet<UploadFileRet>(); 
            if (param.File == null)
            {
                ret.Success = false;
                return ret;
            }

            //保存文件
            var saveFile = await SaveFile(param);

            ret.Success = await saveFile.InsertAsync();
            ret.Data = new UploadFileRet { FileId = saveFile.Id };

            if (ret.Success)
            {
                ret.Message = "上传成功";
            }
            else
            {
                ret.Message = "上传失败";
            }
            return ret;
        }

        /// <summary>
        /// 单文件上传
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ObjectRet<UploadFileRet>> UploadSingleFile(UploadFileParam param)
        {
            var ret = new ObjectRet<UploadFileRet>();
            if(param.File == null)
            {
                ret.Success = false;
                return ret;
            }
            //保存文件
            var saveFile = await SaveFile(param);

            //删除已存在的
            var fileList = await _rep.GetListAsync(x => x.Module == param.Module && x.MainId == param.MainId);
            if (fileList.Any())
            {
                saveFile.DeleteExtraEntity.AddRange(fileList);
            }

            ret.Success = await saveFile.InsertAsync();
            ret.Data = new UploadFileRet 
            { 
                FileId = saveFile.Id,
                FileUrl = GetStreamUrl(saveFile.Id)
            };

            if (ret.Success)
            {
                ret.Message = "上传成功";
            }
            else
            {
                ret.Message = "上传失败";
            }
            return ret;
        }

        /// <summary>
        /// 保存文件到磁盘
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        private async Task<SysFile> SaveFile(UploadFileParam param)
        {
            var webPath = Path.Combine("File", param.Module.ToString(), DateTime.Now.ToString("yyyy-MM-dd"), _currentUser.UserId.ToString());
            var filePath = Path.Combine(AppContext.BaseDirectory, webPath);
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            long Id = SnowFlakeHelper.GetLongId();
            var fileName = Id.ToString() + Path.GetExtension(param.File.FileName);
            var fileFullPath = Path.Combine(filePath, fileName);
            using (var stream = new FileStream(fileFullPath, FileMode.Create))
            {
                await param.File.CopyToAsync(stream);
            }

            var file = new SysFile
            {
                Id = Id,
                Module = param.Module,
                MainId = param.MainId,
                FileType = Path.GetExtension(param.File.FileName),
                ContentType = param.File.ContentType,
                FileSize = param.File.Length,
                FilePath = Path.Combine(webPath, fileName)
            };

            return file;
        }

        public async Task<BaseRet> DeleteFile(long id)
        {
            var ret = new BaseRet();

            var appFile = await _rep.GetByIdAsync(id);
            var filePath = Path.Combine(AppContext.BaseDirectory, appFile.FilePath);
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            ret.Success = await appFile.DeleteAsync();

            if (ret.Success)
            {
                ret.Message = "删除成功";
            }
            else
            {
                ret.Message = "删除失败";
            }
            return ret;
        }

        public async Task<(Stream, string)> GetFileStream(long id)
        {
            var appFile = await _rep.GetByIdAsync(id);
            if (appFile == null)
            {
                return (null, null);
            }
            var filePath = Path.Combine(AppContext.BaseDirectory, appFile.FilePath);
            if (File.Exists(filePath))
            {
                var stream = File.OpenRead(filePath);
                return (stream, appFile.ContentType);
            }
            else
            {
                var stream = new MemoryStream();
                return (stream, appFile.ContentType);
            }
        }

        /// <summary>
        /// 返回获取文件流的地址，前端拼接后端地址
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public string GetStreamUrl(long id)
        {
            return $"/File/GetFileStream/{id}";
        }

        public async Task<string> GetSingleFileId(FileEnum module, long mainId)
        {
            var file = await _rep.GetFirstAsync(x => x.Module == module && x.MainId == mainId);

            if (file != null)
            {
                return file.Id.ToString();
            }
            else
            {
                return "";
            }
        }

        public async Task<string> GetSingleFileStreamUrl(FileEnum module, long mainId)
        {
            var fileId = await GetSingleFileId(module, mainId);
            if (string.IsNullOrEmpty(fileId))
            {
                return string.Empty;
            }
            return GetStreamUrl(Convert.ToInt64(fileId));
        }

        public async Task<string> GetBase64ImageString(FileEnum module, long mainId)
        {
            var file = await _rep.GetFirstAsync(x => x.Module == module && x.MainId == mainId);

            if (file != null) 
            {
                var filePath = Path.Combine(AppContext.BaseDirectory, file.FilePath);
                if (File.Exists(filePath))
                {
                    byte[] bytes = await File.ReadAllBytesAsync(filePath);
                    return $"data:{file.ContentType};base64,{Convert.ToBase64String(bytes)}";
                }
                else
                {
                    return $"data:{file.ContentType};base64,";
                }
            }

            return null;
        }

        public async Task<ObjectRet<SingleImageFileRet>> GetBase64Image(FileEnum module, long mainId)
        {
            var ret = new ObjectRet<SingleImageFileRet>()
            {
                Data = new SingleImageFileRet()
            };
            var file = await _rep.GetFirstAsync(x => x.Module == module && x.MainId == mainId);

            if (file != null) 
            {
                ret.Data.Id = file.Id;

                var filePath = Path.Combine(AppContext.BaseDirectory, file.FilePath);
                if (File.Exists(filePath))
                {
                    byte[] bytes = await File.ReadAllBytesAsync(filePath);
                    ret.Data.Base64Image = $"data:{file.ContentType};base64,{Convert.ToBase64String(bytes)}";
                }
                else
                {
                    ret.Data.Base64Image = $"data:{file.ContentType};base64,";
                }
            }
            else
            {
                ret.Success = false;
            }

            return ret;
        }

        // 根据文件扩展名获取 MIME 类型
        private string GetMimeType(string fileName)
        {
            var provider = new FileExtensionContentTypeProvider();
            if (!provider.TryGetContentType(fileName, out var contentType))
            {
                contentType = "application/octet-stream"; // 默认 MIME 类型
            }
            return contentType;
        }
    }

}
